/*
 * Copyright @ JuCheap All rights reserved.
 * 
 * 功能描述:基础服务文件
 * 作者: JuCheap
 * 时间: 03/13/2019 17:17:44
 */
using AutoMapper;
using JuCheap.Core.Data.Entity;
using JuCheap.Core.Extentions;
using JuCheap.Core.Infrastructure;
using JuCheap.Core.IRepository;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace JuCheap.Core.Service
{
    /// <summary>
    /// 基础服务
    /// </summary>	
    public class BaseService<TModel, TFilter, TEntity> where TEntity : class, IBaseEntity, new()
    {
		private readonly IRepositoryBase<TEntity> _baseRepository;
        private readonly IMapper _mapper;

        /// <summary>
        /// ctor
        /// </summary>
        /// <param name="baseRepository"></param>
        /// <param name="mapper"></param>
		public BaseService(IRepositoryBase<TEntity> baseRepository, IMapper mapper)
		{
            _baseRepository = baseRepository;
            _mapper = mapper;
		}

        /// <summary>
        /// 添加
        /// </summary>
        /// <param name="model">数据模型</param>
        /// <returns></returns>
        public async Task<string> InsertAsync(TModel model)
        {
            var entity = _mapper.Map<TEntity>(model);
            return await _baseRepository.InsertAsync(entity);
        }

        /// <summary>
        /// 批量添加
        /// </summary>
        /// <param name="models">模型集合</param>
        public async Task BatchInsertAsync(List<TModel> models)
        {
            var list = _mapper.Map<List<TEntity>>(models);
            await _baseRepository.BatchInsertAsync(list);
        }

        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="model">数据模型</param>
        /// <returns></returns>
        public async Task UpdateAsync(TModel model)
        {
            var entity = _mapper.Map<TEntity>(model);
            await _baseRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 删除指定主键的数据(逻辑删除)
        /// </summary>
        /// <param name="keyId">主键id</param>
        /// <returns></returns>
        public async Task DeleteAsync(string keyId)
        {
            await _baseRepository.DeleteAsync(keyId);
        }

        /// <summary>
        /// 批量条件删除(逻辑删除)
        /// </summary>
        /// <param name="keyIds">主键Id集合</param>
        /// <returns></returns>
        public async Task DeleteAsync(IList<string> keyIds)
        {
            await _baseRepository.DeleteAsync(keyIds);
        }

        /// <summary>
        /// 根据主键查询实体
        /// </summary>
        /// <param name="keyValue">主键</param>
        /// <returns></returns>
        public async Task<TModel> FindAsync(object keyValue)
        {
            var entity = await _baseRepository.FindAsync(keyValue);
            return _mapper.Map<TModel>(entity);
        }

        /// <summary>
        /// 根据条件查询实体
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        public async Task<TModel> FindAsync(Expression<Func<TEntity, bool>> predicate)
        {
            var entity = await _baseRepository.FindAsync(predicate);
            return _mapper.Map<TModel>(entity);
        }

        /// <summary>
        /// 根据条件查询实体集合
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        public async Task<List<TModel>> FindListAsync(Expression<Func<TEntity, bool>> predicate)
        {
            var entityList = await _baseRepository.Queryable().Where(predicate).ToListAsync();
            return _mapper.Map<List<TModel>>(entityList);
        }

        /// <summary>
        /// 根据条件查询是否存在指定的数据
        /// </summary>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        public async Task<bool> ExistsAsync(Expression<Func<TEntity, bool>> predicate)
        {
            return await _baseRepository.ExistsAsync(predicate);
        }

        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="filter">分页条件</param>
        /// <param name="predicate">条件表达式</param>
        /// <returns></returns>
        public async Task<PagedResult<TModel>> QueryPagesAsync(BaseCondition filter, Expression<Func<TFilter, bool>> predicate)
        {
            var entityPredicate = predicate.Cast<TFilter, TEntity, bool>();
            var pagedResult = await _baseRepository.QueryPagesAsync(filter, entityPredicate);

            var models = _mapper.Map<List<TModel>>(pagedResult.Datas);
            var pageDataInfo = new PagedResult<TModel>
            {
                PageIndex = pagedResult.PageIndex,
                PageSize = pagedResult.PageSize,
                Records = pagedResult.Records,
                Datas = models
            };
            return pageDataInfo;
        }
    }
}
	